/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.transport.ipsec;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;

import cgl.narada.transport.Link;
import cgl.narada.transport.LinkFactory;
import cgl.narada.transport.TransportDebugFlags;
import cgl.narada.transport.TransportException;
import cgl.narada.transport.TransportHandler;
import cgl.narada.util.ProcessLauncher;

/**
 * This is a IPSec implementation of the LinkFactory Interface. This particular
 * implementation of the LinkFactory interface is a little different from all
 * other implementations of the interface in that it does not require any
 * specific properties to be specified for the initialization of the factory
 * 
 * @author Shrideep Pallickara 
 * @author Craig Shue
 * 
 * $Date$ $Revision$
 */

public class IPSecLinkFactory implements LinkFactory, TransportDebugFlags {

    private String managedLinkType = "ipsec";

    private Properties factoryProperties;

    private String moduleName = "IPSecLinkFactory: ";


    private TransportHandler transportHandler;
    
    private IPSecTunneler ipSecTunneler;

    public IPSecLinkFactory() {
        ipSecTunneler = IPSecTunneler.getInstance();
    }

    /*
     * These are the set of factoryProperties that are needed to set up the link
     * Factory.
     */
    public void setLinkFactoryProperties(Properties properties) {
        factoryProperties = properties;
    }

    /** Return the type of all the links created/managed by this factory */
    public String getManagedLinksType() {
        return managedLinkType;
    }

    /**
     * Create a communication link based on the factoryProperties that have been
     * specified.
     */
    public Link createLink(Properties linkProperties) throws TransportException {
        String ipSecHostname = ipSecTunneler.createTunnel(linkProperties);
        String linkId = "ipsec://" + ipSecHostname;
        IPSecLink ipSecLink = new IPSecLink();
        ipSecLink.setLinkId(linkId);
        
        return ipSecLink;
    }

    /**
     * Set the interval for checking status of all links managed by this factory
     * to the one specified in the argument
     */
    public void setLinkStatusInterval(long interval) {

    }

    /**
     * Start communication services. In the case of IPSec for example, the
     * thread which incorporates the serverSocket.accept() is started
     */
    public boolean loadLinkFactoryServices() throws TransportException {
        /** Currently we do not require specific operations to initialize 
         * the IPSec link Factory */
        return true;
    }

    /**
     * Indicates if this factory can manage migration of links of a certain type
     */
    public boolean canManageLinkMigrationOfType(String linkType) {
        /** NBNI */
        return false;
    }

    /**
     * Used to migrate communications of a link to the one supported by links
     * managed by this factory
     */
    public void manageLinkMigration(Link link) throws TransportException {
        /** NBNI */
    }

    /**
     * Sets the reference to the transport handler. This is done during the
     * loadLinkFactory() operation within the transport handler implementations.
     */
    public void setTransportHandler(TransportHandler transportHandler) {
        this.transportHandler = transportHandler;
    }

    /**
     * This method is used to garbage collect any resources associated with the
     * link factory
     */
    public void dispose() {
        ipSecTunneler.disposeAllTunnels();
    }

    public TransportHandler getTransportHandler() {
        if (transportHandler == null) {
            System.out.println(moduleName
                + "TransportHandler reference is NULL");
        }
        return transportHandler;
    }

}
